import json

from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from fdfs_client.client import Fdfs_client

from utils.loading_html import load_html
from utils.response_code import *
from django.views import View
from .models import Area, House, Facility, HouseImage
from django.http import JsonResponse, HttpResponse


class AreasView(View):
    def get(self, request):
        """获取城区列表"""

        areas = Area.objects.all()
        areas_list = []
        for area in areas:
            areas_list.append({
                'aid': area.id,
                'aname': area.name
            })

        return JsonResponse({
            'errno': 0,
            'errmsg': '获取成功',
            'data': areas_list
        })


class LoadMyHouseView(LoginRequiredMixin, View):
    def get(self, request):
        """加载我的房源页面"""
        return HttpResponse(load_html('/static/myhouse.html'), status=200)


class LoadNewHouseView(LoginRequiredMixin, View):
    def get(self, request):
        """加载发布房源页面"""
        return HttpResponse(load_html('/static/newhouse.html'), status=200)


class HousesView(View):
    def post(self, request):
        """发布新房源"""

        # 获取数据
        recv_data = json.loads(request.body)

        user = request.user
        if not user.is_authenticated:
            return JsonResponse({
                'errno': RET.SESSIONERR,
                'errmsg': error_map[RET.SESSIONERR]
            })

        facilities = recv_data.pop('facility')
        house = House.objects.create(user=request.user, **recv_data)
        for facility in facilities:
            house.facility.add(Facility.objects.get(id=facility))
        house.save()

        # 返回响应
        return JsonResponse({
            'errno': 0,
            'errmsg': '发布成功',
            'data': {
                'house_id': house.id
            }
        })

    def get(self, request):
        # 接收数据
        area_id = request.GET.get('aid')
        start_date = request.GET.get('sd')
        end_date = request.GET.get('ed')
        sort_key = request.GET.get('sk')
        page = request.GET.get('p')

        # 校验数据
        if not all([area_id, start_date, end_date, sort_key, page]):
            return JsonResponse({
                'errno': RET.PARAMERR,
                'errmsg': error_map[RET.PARAMERR]
            })

        try:
            area = Area.objects.get(id=area_id)
        except:
            return JsonResponse({
                'errno': RET.PARAMERR,
                'errmsg': error_map[RET.PARAMERR]
            })

        try:
            page = int(page)
        except:
            return JsonResponse({
                'errno': RET.PARAMERR,
                'errmsg': error_map[RET.PARAMERR]
            })

        from datetime import datetime
        start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
        end_date = datetime.strptime(end_date, '%Y-%m-%d').date()
        days = (end_date - start_date).days

        # 过滤房源并排序
        from django.db.models import Q
        houses = House.objects.filter(
            Q(area_id=area_id) & Q(min_days__lte=days) & (Q(max_days=0) | Q(max_days__gte=days)))

        if sort_key == 'booking':
            houses = houses.order_by('-order_count')
        elif sort_key == 'price-inc':
            houses = houses.order_by('price')
        elif sort_key == 'price-des':
            houses = houses.order_by('-price')
        else:
            houses = houses.order_by('-create_time')

        houses_list = []
        for house in houses:
            orders = house.order_set.filter(status__in=(1, 2, 3, 4))
            for order in orders:
                if order.begin_date >= end_date or order.end_date <= start_date:
                    pass
                else:
                    break
            else:
                houses_list.append(house)

        # 分页
        count = len(houses_list)
        from math import ceil
        total_page = ceil(count / 5)

        if page < total_page:
            res_houses = houses_list[(page - 1) * 5: page * 5]
        else:
            res_houses = houses_list[(page - 1) * 5:]

        # 生成数据
        houses_list = []
        for house in res_houses:
            houses_list.append({
                "address": house.address,
                "area_name": house.area.name,
                "ctime": house.create_time.date(),
                "house_id": house.id,
                "img_url": settings.BASE_URL + house.index_image_url,
                "order_count": house.order_count,
                "price": house.price,
                "room_count": house.room_count,
                "title": house.title,
                "user_avatar": house.user.avatar.url

            })

        # 返回响应
        return JsonResponse({
            'errno': 0,
            'errmsg': '请求成功',
            'data': {
                'houses': houses_list,
                'total_page': 2
            }
        })


class UploadHouseImageView(LoginRequiredMixin, View):
    def post(self, request, house_id):
        """上传房源图片"""

        # 获取并校验数据
        image = request.FILES.get('house_image')
        if not image:
            return JsonResponse({
                'errno': RET.PARAMERR,
                'errmsg': error_map[RET.PARAMERR]
            })

        try:
            house = House.objects.get(id=house_id)
        except:
            return JsonResponse({
                'errno': RET.NODATA,
                'errmsg': error_map[RET.NODATA]
            })

        # 使用fdfs上传图片
        client = Fdfs_client(settings.BASE_DIR + '/utils/fdfs/client.conf')
        image_buffer = image.read()
        result = client.upload_by_buffer(image_buffer)

        # 判断是否上传成功
        if result['Status'] != 'Upload successed.':
            return JsonResponse({
                'errno': RET.THIRDERR,
                'errmsg': error_map[RET.THIRDERR]
            })

        # 获取图片地址，写入数据库
        image_url = result['Remote file_id']
        if not house.index_image_url:
            house.index_image_url = image_url
            house.save()
        HouseImage.objects.create(
            house=house,
            url=image_url
        )

        return JsonResponse({
            'errno': 0,
            'errmsg': '图片上传成功',
            'data': {
                'url': settings.BASE_URL + image_url
            }
        })


class MyHouseView(LoginRequiredMixin, View):
    def get(self, request):
        """获取我的房源列表"""

        user = request.user
        houses = user.houses.all()
        houses_list = []
        for house in houses:
            houses_list.append({
                "address": house.address,
                "area_name": house.area.name,
                "ctime": house.create_time.date(),
                "house_id": house.id,
                "img_url": settings.BASE_URL + house.index_image_url,
                "order_count": house.order_count,
                "price": house.price,
                "room_count": house.room_count,
                "title": house.title,
                "user_avatar": user.avatar.url
            })

        return JsonResponse({
            'data': {
                'houses': houses_list
            },
            'errno': RET.OK,
            'errmsg': error_map[RET.OK]
        })


class HomeRecommendHousesView(View):
    def get(self, request):
        """首页房源推荐"""
        houses = House.objects.order_by('-create_time')[0: 5]

        houses_list = []
        for house in houses:
            houses_list.append({
                'house_id': house.id,
                'img_url': settings.BASE_URL + house.index_image_url,
                'title': house.title
            })

        return JsonResponse({
            'errno': 0,
            'errmsg': 'OK',
            'data': houses_list
        })
